"use strict";
const path = require("path");
const cp = require("child_process");
const Package = require("@unluna/package");
const log = require("@unluna/log");

const SETTINGS = {
	// "init": "@unluna/core",
	"init": "@imooc-cli/init"
};

// const exec = (projectName, opts, cmd) => {
const exec = async (...args) => {
	const CACHE_DIR = "dependencies";
	let targetPath = process.env.CLI_TARGET_PATH || "";
	let storeDir = path.resolve(targetPath, "node_modules");
	let pkg;
	const [, , cmd] = args;
	const cmdName = cmd.name();
	const packageName = SETTINGS[cmdName];
	const packageVersion = "latest";

	// 如果没有指定本地文件路径，则使用用户电脑的home目录
	if (!targetPath) {
		const homePath = process.env.CLI_HOME_PATH;
		targetPath = path.resolve(homePath, CACHE_DIR);
		storeDir = path.resolve(targetPath, "node_modules");
		log.verbose("targetPath", targetPath);
		log.verbose("storeDir", storeDir);

		pkg = new Package({
			targetPath,
			storeDir,
			packageName,
			packageVersion
		});
		// package存在，更新package
		if (await pkg.exists()) {
			await pkg.update();
		}
		// package不存在，安装package
		else {
			await pkg.install();
		}
	} else {
		pkg = new Package({
			targetPath,
			packageName,
			packageVersion
		});
	}
	const rootFilePath = pkg.getRootFilePath();

	if (rootFilePath) {
		try {
			// 因为有循环引用的问题，所以要把不需要的东西干掉
			const cmd = args[args.length - 1];
			const o = Object.create(null);
			Object.keys(cmd).forEach((key) => {
				// hasOwnProperty:用于检查对象自身（不包括原型链上的属性）是否具有指定的属性。返回一个布尔值。
				if (cmd.hasOwnProperty(key) && !key.startsWith("_") && key !== "parent") {
					o[key] = args[key];
				}
			});
			args[args.length - 1] = o;
			const code = `require('${rootFilePath}').call(null, ${JSON.stringify(args)})`;
			const childProcess = spawn("node", ["-e", code], {
				cwd: process.cwd(),
				stdio: "inherit",
				env: process.env
			});
			childProcess.on("exit", (code) => {
				log.verbose("命令执行成功！");
				process.exit(code);
			});
			childProcess.on("error", (e) => {
				log.error(e.message);
				process.exit(1);
			});
		} catch (e) {
			log.error(e.message);
			process.exit(1);
		}
	}
};

// 兼容windows平台
const spawn = (command, args, options = {}) => {
	const isWin32 = process.platform === "win32";
	const _cmd = isWin32 ? "cmd" : command;
	// /c 静默状态执行
	// cp.spawn('cmd', ['/c', 'node', '-e', code])
	const _args = isWin32 ? ["/c", command, ...args] : args;
	return cp.spawn(_cmd, _args, options);
};

module.exports = exec;

